home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / viewers / ham8_jpg.lha / ham8-jpeg / Source / al-j.c < prev    next >
C/C++ Source or Header  |  1992-12-20  |  13KB  |  570 lines

  1. /*
  2.  * Al-j.c Michael Saunby    M.Saunby@reading.ac.uk
  3.  *
  4.  * Release 1.1  December 1992 Jpeg viewer using Albert HAM8 public screen and
  5.  * Independent JPEG groups jpeg decompressor.
  6.  */
  7. #define PROG_NAME "Al-J JPEG Viewer"
  8. #define COPYRIGHT_MESSAGE "Version 1.1\nDecember 1992\n\nCopyright ⌐ 1992\n\
  9. Michael Saunby\n\
  10. \nThis program is based in part\n\
  11. on the work of the Independent\n\
  12. JPEG Group"
  13.  
  14. #include <intuition/intuition.h>
  15. #include <intuition/gadgetclass.h>
  16. #include <graphics/gfxbase.h>
  17. #include <graphics/displayinfo.h>
  18. #include <intuition/screens.h>
  19. #include <dos/dosextens.h>
  20. #include <dos/dosasl.h>
  21. #include <libraries/gadtools.h>
  22.  
  23. #include <clib/asl_protos.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/intuition_protos.h>
  26. #include <clib/layers_protos.h>
  27. #include <clib/graphics_protos.h>
  28. #include <clib/gadtools_protos.h>
  29. #include <clib/dos_protos.h>
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include "display24.h"
  36.  
  37. /* Values greater than 1 give bad pixels, why? */
  38. #define ARRAY24_MAX_ROWS 1
  39.  
  40. /*
  41.  * ReadArgs() template
  42.  */
  43. #define TEMPLATE "NAME"
  44. #define OPT_NAME 0
  45. #define OPT_COUNT 1
  46.  
  47. int JPEG_restart = 0;        /* set to 1 for New file */
  48.  
  49. struct IntuitionBase *IntuitionBase = NULL;
  50. struct GfxBase *GfxBase = NULL;
  51. struct Library *GadToolsBase = NULL;
  52. struct Library *AslBase = NULL;
  53. extern struct ExecBase *SysBase;
  54.  
  55. /* following for 24 bit put row */
  56. SHORT ham8_line;        /* screen line number to draw at */
  57. UBYTE *ham8_pens = NULL;
  58. struct RastPort ham8_temprp;
  59. struct BitMap *temp_bm = NULL;
  60. struct Screen *screen = NULL;
  61. struct FileRequester *filereq = NULL;
  62. struct BitMap *bitmap = NULL;
  63. struct Window *window = NULL;
  64. struct Menu *menu;
  65. struct Gadget *gadgets, *horprop = NULL, *vertprop = NULL;
  66. void *vi;
  67. ULONG allocsignal;
  68.  
  69. /* gadget ids */
  70. #define HORPROP     1
  71. #define VERTPROP     2
  72. /* current x and y offsets */
  73. LONG scroll_x = 0;
  74. LONG scroll_y = 0;
  75. LONG window_max_w;
  76. LONG window_max_h;
  77.  
  78. struct EasyStruct failedES =
  79. {sizeof (struct EasyStruct), 0, PROG_NAME,
  80.  "%s", "OK",};
  81.  
  82. #define OPEN 1
  83. #define ABOUT 2
  84. #define QUIT 3
  85. struct NewMenu prj_menu[] =
  86. {
  87.   {NM_TITLE, "Project", 0, 0, 0, 0,},
  88.   {NM_ITEM, "Open...", "O", 0, 0, (void *) OPEN,},
  89.   {NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
  90.   {NM_ITEM, "About...", "?", 0, 0, (void *) ABOUT,},
  91.   {NM_ITEM, "Quit", "Q", 0, 0, (void *) QUIT,},
  92.   {NM_END, NULL, 0, 0, 0, 0,},
  93. };
  94.  
  95. void
  96. Cleanup ()
  97. {
  98.   if (screen)
  99.     UnlockPubScreen (NULL, screen);
  100.   screen = NULL;
  101.  
  102.   if (window)
  103.     {
  104.       ReleasePens (&(window->WScreen->ViewPort));
  105.       FreeVisualInfo (vi);
  106.       CloseWindow (window);
  107.       gadgets = NULL;
  108.     }
  109.   window = NULL;
  110.  
  111.   if (menu)
  112.     ClearMenuStrip (window);
  113.   menu = NULL;
  114.   if (horprop)
  115.     DisposeObject (horprop);
  116.   horprop = NULL;
  117.   if (vertprop)
  118.     DisposeObject (vertprop);
  119.   vertprop = NULL;
  120.   if (ham8_pens)
  121.     FreeMem (ham8_pens, ((temp_bm->BytesPerRow << 3) * temp_bm->Rows));
  122.   ham8_pens = NULL;
  123.   if (temp_bm)
  124.     FreeBitMap (temp_bm);
  125.   temp_bm = NULL;
  126.   if (bitmap)
  127.     FreeBitMap (bitmap);
  128.   bitmap = NULL;
  129.   if (!JPEG_restart)
  130.     {
  131.       if (filereq)
  132.     FreeAslRequest (filereq);
  133.       filereq = NULL;
  134.       if (AslBase)
  135.     CloseLibrary (AslBase);
  136.       AslBase = NULL;
  137.       if (GadToolsBase)
  138.     CloseLibrary (GadToolsBase);
  139.       GadToolsBase = NULL;
  140.       if (IntuitionBase)
  141.     CloseLibrary ((struct Library *) IntuitionBase);
  142.       IntuitionBase = NULL;
  143.       if (GfxBase)
  144.     CloseLibrary ((struct Library *) GfxBase);
  145.       GfxBase = NULL;
  146.     }
  147. }
  148.  
  149. void
  150. Quit (char whytext[], UBYTE failcode)
  151. {
  152.   EasyRequest (NULL, &failedES, NULL, whytext);
  153.   Cleanup ();
  154.   exit (failcode);
  155. }
  156.  
  157. void
  158. UserWait ()
  159. {
  160.   struct IntuiMessage *msg;
  161.   struct Gadget *gadget;
  162.   BOOL abort = FALSE;
  163.   UWORD class, code;
  164.   LONG new_x, new_y;
  165.  
  166.   SetGadgetAttrs (horprop, window, NULL,
  167.           GA_Disabled, FALSE,
  168.           TAG_END);
  169.   SetGadgetAttrs (vertprop, window, NULL,
  170.           GA_Disabled, FALSE,
  171.           TAG_END);
  172.  
  173.   do
  174.     {
  175.       WaitPort (window->UserPort);
  176.  
  177.       while (msg = GT_GetIMsg (window->UserPort))
  178.     {
  179.       code = msg->Code;
  180.       class = msg->Class;
  181.       gadget = (struct Gadget *) msg->IAddress;
  182.       GT_ReplyIMsg (msg);
  183.       switch (class)
  184.         {
  185.         case IDCMP_MENUPICK:
  186.           switch ((UWORD) MENU_USERDATA (ItemAddress (menu, code)))
  187.         {
  188.         case QUIT:
  189.           abort = TRUE;
  190.           break;
  191.         case OPEN:
  192.           JPEG_restart = TRUE;
  193.           abort = TRUE;
  194.           break;
  195.         case ABOUT:
  196.           EasyRequest (window, &failedES,
  197.                    NULL,
  198.                    COPYRIGHT_MESSAGE);
  199.           break;
  200.         }
  201.           break;
  202.         case IDCMP_CLOSEWINDOW:
  203.           abort = TRUE;
  204.           break;
  205.         case IDCMP_SIZEVERIFY:
  206.         case IDCMP_NEWSIZE:
  207.           SetGadgetAttrs (vertprop, window, NULL,
  208.                   PGA_Visible, window->GZZHeight,
  209.                   TAG_END);
  210.           SetGadgetAttrs (horprop, window, NULL,
  211.                   PGA_Visible, window->GZZWidth,
  212.                   TAG_END);
  213.           break;
  214.         case IDCMP_GADGETUP:
  215.           switch (gadget->GadgetID)
  216.         {
  217.         case HORPROP:
  218.           GetAttr (PGA_Top, horprop, &new_x);
  219.           ScrollLayer (0L, window->RPort->Layer, new_x - scroll_x, 0);
  220.           scroll_x = new_x;
  221.           WindowLimits (window, 0, 0, window_max_w - scroll_x, 0);
  222.           break;
  223.  
  224.         case VERTPROP:
  225.           GetAttr (PGA_Top, vertprop, &new_y);
  226.           ScrollLayer (0L, window->RPort->Layer, 0, new_y - scroll_y);
  227.           scroll_y = new_y;
  228.           WindowLimits (window, 0, 0, 0, window_max_h - scroll_y);
  229.           break;
  230.         }
  231.  
  232.           break;
  233.         default:
  234.           /*
  235.            * EasyRequest(window, &failedES, NULL, "Bogus message
  236.            * sorry!");
  237.            */
  238.           break;
  239.         }
  240.  
  241.     }
  242.   } while (abort == FALSE);
  243.  
  244.   Cleanup ();
  245.  
  246. }
  247.  
  248. char *
  249. Startup (char *namebuf)
  250. {
  251.   char *ret_code = NULL;
  252.   LONG result[OPT_COUNT] =
  253.   {0};
  254.   struct RDArgs *rda;
  255.  
  256.   if (!JPEG_restart)
  257.     {
  258.       if ((GfxBase =
  259.        (struct GfxBase *) OpenLibrary ("graphics.library", 36)) == NULL)
  260.     Quit ("graphics.library is too old <V36", 25);
  261.  
  262.       if ((IntuitionBase =
  263.        (struct IntuitionBase *) OpenLibrary ("intuition.library", 36)) == NULL)
  264.     Quit ("intuition.library is too old <V36", 25);
  265.  
  266.       if ((AslBase = OpenLibrary ("asl.library", 36)) == NULL)
  267.     Quit ("asl.library is too old <V36", 25);
  268.  
  269.       if ((GadToolsBase = OpenLibrary ("gadtools.library", 36)) == NULL)
  270.     Quit ("gadtools.library is too old <V36", 25);
  271.  
  272.       if ((filereq =
  273.        (struct FileRequester *) AllocAslRequestTags (ASL_FileRequest,
  274.                       ASLFR_PubScreenName, HAM8_ALBERT_NAME,
  275.                              TAG_END))
  276.       == NULL)
  277.     Quit ("could not build file requster", 25);
  278.  
  279.       rda = ReadArgs (TEMPLATE, result, NULL);
  280.  
  281.       if (result[OPT_NAME])
  282.     {
  283.       strcpy (namebuf, (UBYTE *) result[OPT_NAME]);
  284.       ret_code = namebuf;
  285.     }
  286.       FreeArgs (rda);
  287.     }
  288.   JPEG_restart = FALSE;
  289.  
  290.   if (ret_code == NULL)
  291.     {
  292.       struct Screen *screen;
  293.       /*
  294.        * Opening the File Requester does not bring screen to front. Passing
  295.        * the name ie. UnlockPubscreen(HAM8_ALBERT_NAME, NULL) is allowed
  296.        * but not recommended. I haven't tried it.
  297.        */
  298.       if ((screen = LockPubScreen (HAM8_ALBERT_NAME)) != NULL)
  299.     {
  300.       ScreenToFront (screen);
  301.       UnlockPubScreen (NULL, screen);
  302.     }
  303.       if (AslRequest (filereq, 0L))
  304.     {
  305.       if(filereq->rf_Dir[strlen(filereq->rf_Dir)-1] == ':')
  306.       sprintf (namebuf, "%s%s", filereq->rf_Dir, filereq->rf_File);
  307.       else
  308.       sprintf (namebuf, "%s/%s", filereq->rf_Dir, filereq->rf_File);
  309.       ret_code = namebuf;
  310.     }
  311.     }
  312.   ham8_line = 0;
  313.  
  314.   return (ret_code);
  315. }
  316.  
  317.  
  318. void
  319. CreateWindow (UWORD width, UWORD height)
  320. {
  321.   int pen_errors;
  322.  
  323.   struct Gadget **tmpgad;
  324.  
  325.   if ((menu = CreateMenus (prj_menu, GTMN_FrontPen, 1, TAG_DONE)) == NULL)
  326.     Quit ("could not build menu", 25);
  327.  
  328.   if ((screen = LockPubScreen (HAM8_ALBERT_NAME)) == NULL)
  329.     Quit ("could not find screen", 25);
  330.  
  331.   if ((bitmap = AllocBitMap (width, height, 8, BMF_DISPLAYABLE | BMF_CLEAR,
  332.                  NULL)) == NULL)
  333.     Quit ("could not allocate bitmap", 25);
  334.   gadgets = NULL;
  335.   tmpgad = &gadgets;
  336.  
  337.   /* Create scroller gadgets */
  338.   horprop = (struct Gadget *) NewObject (NULL, "propgclass",
  339.                      GA_Immediate, TRUE,
  340.                      GA_BottomBorder, TRUE,
  341.                      GA_GZZGadget, TRUE,
  342.                      GA_RelVerify, TRUE,
  343.                      PGA_Freedom, FREEHORIZ,
  344.                      PGA_Borderless, FALSE,
  345.                      PGA_NewLook, TRUE,
  346.                      GA_RelBottom, -10,
  347.                      GA_RelWidth, -21,
  348.                      GA_Left, 3,
  349.                      GA_Height, 7,
  350.                      PGA_Top, 0,
  351.                      PGA_Visible, width,
  352.                      PGA_Total, width,
  353.                      GA_ID, HORPROP,
  354.                      GA_Previous, tmpgad,
  355.                      TAG_END);
  356.  
  357.   vertprop = (struct Gadget *) NewObject (NULL, "propgclass",
  358.                       GA_Immediate, TRUE,
  359.                       GA_RightBorder, TRUE,
  360.                       GA_GZZGadget, TRUE,
  361.                       GA_RelVerify, TRUE,
  362.                       PGA_Freedom, FREEVERT,
  363.                       PGA_Borderless, FALSE,
  364.                       PGA_NewLook, TRUE,
  365.                       GA_RelHeight, -21,
  366.                       GA_RelRight, -13,
  367.                       GA_Width, 10,
  368.                       GA_Top, 10,
  369.                       PGA_Top, 0,
  370.                       PGA_Visible, height,
  371.                       PGA_Total, height,
  372.                       GA_ID, VERTPROP,
  373.                       GA_Previous, tmpgad,
  374.                       TAG_END);
  375.  
  376.   if ((window = OpenWindowTags (NULL,
  377.                 WA_Title, PROG_NAME,
  378.                 WA_Top, screen->BarHeight + 1,
  379.                 WA_InnerHeight, height,
  380.                 WA_InnerWidth, width,
  381.                 WA_NewLookMenus, TRUE,
  382.                 WA_PubScreen, screen,
  383.                 WA_SizeGadget, TRUE,
  384.                 WA_DepthGadget, TRUE,
  385.                 WA_DragBar, TRUE,
  386.                 WA_CloseGadget, TRUE,
  387.                 WA_Activate, FALSE,
  388.                 WA_SizeBBottom, TRUE,
  389.                 WA_SizeBRight, TRUE,
  390.                 WA_MinWidth, 64,
  391.                 WA_MinHeight, 32,
  392.                 WA_MaxWidth, -1,
  393.                 WA_MaxHeight, -1,
  394.                 WA_AutoAdjust, TRUE,
  395.                 WA_SuperBitMap, bitmap,
  396.                 WA_GimmeZeroZero, TRUE,
  397.                 WA_Gadgets, gadgets,
  398.                 WA_IDCMP, MENUPICK | IDCMP_NEWSIZE |
  399.                 IDCMP_SIZEVERIFY | CLOSEWINDOW | GADGETUP,
  400.                 TAG_END)) == NULL)
  401.     {
  402.       Quit ("could not open window\nProbably not enough chip ram", 25);
  403.     }
  404.   vi = GetVisualInfo (screen, TAG_END);
  405.   /*
  406.    * Have window now so no longer need lock on screen.
  407.    */
  408.  
  409.   UnlockPubScreen (NULL, screen);
  410.   screen = NULL;
  411.  
  412.   if (LayoutMenus (menu, vi, TAG_DONE) == NULL)
  413.     Quit ("could not layout menu", 25);
  414.   SetMenuStrip (window, menu);
  415.  
  416.   /*
  417.    * The window may not have opened at the size we asked for so fix the
  418.    * prop gads.
  419.    */
  420.   SetGadgetAttrs (horprop, window, NULL,
  421.           PGA_Visible, window->GZZWidth,
  422.           PGA_Top, 0,
  423.           GA_Disabled, TRUE,
  424.           TAG_END);
  425.   SetGadgetAttrs (vertprop, window, NULL,
  426.           PGA_Visible, window->GZZHeight,
  427.           PGA_Top, 0,
  428.           GA_Disabled, TRUE,
  429.           TAG_END);
  430.  
  431.   window_max_w = window->Width;
  432.   window_max_h = window->Height;
  433.   scroll_x = 0;
  434.   scroll_y = 0;
  435.   WindowLimits (window, 0, 0, window_max_w, window_max_h);
  436.  
  437.   CopyMem (&(window->RPort), &ham8_temprp, sizeof (struct RastPort));
  438.   ham8_temprp.Layer = NULL;
  439.   if ((temp_bm = AllocBitMap (width, /* height */ 1, /* depth */ 8, 0L, bitmap)) == NULL)
  440.     Quit ("cannot get line bitmap", 25);
  441.   ham8_temprp.BitMap = temp_bm;
  442.   ham8_pens = AllocMem (((temp_bm->BytesPerRow << 3) * ARRAY24_MAX_ROWS), 0L);
  443.   /*
  444.    * Get a copy of the special palette. The palette is set when the screen
  445.    * is created.
  446.    */
  447.   pen_errors = StandardPalette (&(window->WScreen->ViewPort), TRUE);
  448.   if (pen_errors)
  449.     EasyRequest (window, &failedES,
  450.          NULL,
  451.          "Could not find full HAM-8 Albert palette");
  452.  
  453. }
  454.  
  455. #undef GLOBAL            /* Means something else to IJPEG code */
  456. #include "jinclude.h"
  457.  
  458. #ifndef EIGHT_BIT_SAMPLES
  459. Sorry, this code only copes with 8 - bit JSAMPLEs.    /* deliberate syntax err */
  460. #endif
  461.  
  462.  
  463. /*
  464.  * Write the file header.
  465.  */
  466.  
  467. METHODDEF void
  468. output_init (decompress_info_ptr cinfo)
  469. {
  470.   CreateWindow ((SHORT) cinfo->image_width, (SHORT) cinfo->image_height);
  471.  
  472. }
  473.  
  474.  
  475. /*
  476.  * Write some pixel data.
  477.  */
  478.  
  479. METHODDEF void
  480. put_pixel_rows (decompress_info_ptr cinfo, int num_rows,
  481.         JSAMPIMAGE pixel_data)
  482. {
  483.   JSAMPROW ptr0, ptr1, ptr2;
  484.   long width = cinfo->image_width;
  485.   int row, height;
  486.  
  487.       for (row = 0; row < num_rows; row += height)
  488.     {
  489.       ptr0 = pixel_data[0][row];
  490.       ptr1 = pixel_data[1][row];
  491.       ptr2 = pixel_data[2][row];
  492.       height = num_rows - row;    /* ie rows left */
  493.       height = (ARRAY24_MAX_ROWS < height) ? ARRAY24_MAX_ROWS : height;
  494.  
  495.       WritePixelArray24 (window->RPort, 0, ham8_line,
  496.                  width, height,
  497.                  ptr0, ptr1, ptr2, ham8_pens, &ham8_temprp);
  498.       ham8_line += height;
  499.     }
  500. }
  501.  
  502. METHODDEF void
  503. put_gray_rows (decompress_info_ptr cinfo, int num_rows,
  504.         JSAMPIMAGE pixel_data)
  505. {
  506.   JSAMPROW ptr0;
  507.   long width = cinfo->image_width;
  508.   int row, height;
  509.  
  510.  
  511.       for (row = 0; row < num_rows; row += height)
  512.     {
  513.       ptr0 = pixel_data[0][row];
  514.       height = num_rows - row;    /* ie rows left */
  515.       height = (ARRAY24_MAX_ROWS < height) ? ARRAY24_MAX_ROWS : height;
  516.  
  517.     /* Dont have a special grayscale function yet */
  518.       WritePixelArray24 (window->RPort, 0, ham8_line,
  519.                  width, height,
  520.                  ptr0, ptr0, ptr0, ham8_pens, &ham8_temprp);
  521.       ham8_line += height;
  522.     }
  523. }
  524.  
  525. /*
  526.  * Might be nice to try quantized output sometime.
  527.  */
  528.  
  529. METHODDEF void
  530. put_demapped_rows (decompress_info_ptr cinfo, int num_rows,
  531.            JSAMPIMAGE pixel_data)
  532. {
  533. }
  534. METHODDEF void
  535. put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  536. {
  537.  
  538. }
  539.  
  540.  
  541. /*
  542.  * Finish up at the end of the file.
  543.  */
  544.  
  545. METHODDEF void
  546. output_term (decompress_info_ptr cinfo)
  547. {
  548.   UserWait ();
  549. }
  550.  
  551.  
  552. /*
  553.  * The method selection routine for HAM8 format output. This should be called
  554.  * from d_ui_method_selection if HAM8 output is wanted.
  555.  */
  556.  
  557. GLOBAL void
  558. jselwham8 (decompress_info_ptr cinfo)
  559. {
  560.  
  561.  
  562.   cinfo->methods->output_init = output_init;
  563.   cinfo->methods->put_color_map = put_color_map;
  564.   if(cinfo->out_color_space == CS_RGB)
  565.       cinfo->methods->put_pixel_rows = put_pixel_rows;
  566.   else
  567.       cinfo->methods->put_pixel_rows = put_gray_rows;
  568.   cinfo->methods->output_term = output_term;
  569. }
  570.